package judesart.app.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotNull;

import com.google.appengine.api.datastore.Text;

@Entity
@NamedQueries( {
        @NamedQuery(name = "Exhibition.countByArtistId", query = "select count(o) from Exhibition o where o.artistId = :artistId"),
        @NamedQuery(name = "Exhibition.findByArtistId", query = "select o from Exhibition o where o.artistId = :artistId order by o.startDate desc") })
public class Exhibition implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Basic
    @NotNull
    private Long artistId;

    @Basic
    private Date startDate;

    @Basic
    private Date endDate;

    @Basic
    @Enumerated(EnumType.STRING)
    private ExhibitionType type;

    @Basic
    private String title;

    @Basic
    private Text detail;

    @Basic
    private String curator;

    @Basic
    private List<String> exhibitingArtists;

    @ManyToOne(cascade = CascadeType.ALL)
    private Address galleryAddress;

    @Basic
    private String galleryName;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "exhibition")
    private List<ExhibitionPhoto> photos = new ArrayList<ExhibitionPhoto>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "exhibition")
    private List<ExhibitionVideo> videos = new ArrayList<ExhibitionVideo>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "exhibition")
    private List<ExhibitionArtwork> artworks = new ArrayList<ExhibitionArtwork>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public ExhibitionType getType() {
        return type;
    }

    public void setType(ExhibitionType type) {
        this.type = type;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Text getDetail() {
        return detail;
    }

    public void setDetail(Text detail) {
        this.detail = detail;
    }

    public String getCurator() {
        return curator;
    }

    public void setCurator(String curator) {
        this.curator = curator;
    }

    public List<String> getExhibitingArtists() {
        return exhibitingArtists;
    }

    public void setExhibitingArtists(List<String> exhibitingArtists) {
        this.exhibitingArtists = exhibitingArtists;
    }

    public Address getGalleryAddress() {
        return galleryAddress;
    }

    public void setGalleryAddress(Address galleryAddress) {
        this.galleryAddress = galleryAddress;
    }

    public String getGalleryName() {
        return galleryName;
    }

    public void setGalleryName(String galleryName) {
        this.galleryName = galleryName;
    }

    public List<ExhibitionPhoto> getPhotos() {
        return photos;
    }

    public void setPhotos(List<ExhibitionPhoto> photos) {
        this.photos = photos;
    }

    public List<ExhibitionVideo> getVideos() {
        return videos;
    }

    public void setVideos(List<ExhibitionVideo> videos) {
        this.videos = videos;
    }

    public List<ExhibitionArtwork> getArtworks() {
        return artworks;
    }

    public void setArtworks(List<ExhibitionArtwork> artworks) {
        this.artworks = artworks;
    }

    public void addArtwork(Artwork artwork) {
        if (getArtworks() == null)
            setArtworks(new ArrayList<ExhibitionArtwork>());
        for (ExhibitionArtwork exhiArt : getArtworks()) {
            if (exhiArt.getArtworkId().longValue() == artwork.getId().longValue()) {
                return;
            }
        }
        ExhibitionArtwork exhibitionArtwork = new ExhibitionArtwork();
        exhibitionArtwork.setArtworkId(artwork.getId());
        exhibitionArtwork.setExhibition(this);
        getArtworks().add(exhibitionArtwork);

    }

    public void addPhoto(Image image) {
        ExhibitionPhoto photo = new ExhibitionPhoto();
        photo.setExhibition(this);
        photo.setImageId(image.getId());
        if (getPhotos() == null) {
            setPhotos(new ArrayList<ExhibitionPhoto>());
        }
        if (getPhotos().size() == 0)
        	photo.setMainImage(true);
        else
        	photo.setMainImage(false);
        getPhotos().add(photo);
    }

    public ExhibitionVideo addVideo(String videoId) {
        ExhibitionVideo video = new ExhibitionVideo();
        video.setExhibition(this);
        video.setVideoId(videoId);
        if (getVideos() == null)
            setVideos(new ArrayList<ExhibitionVideo>());
        getVideos().add(video);
        return video;
    }

    public boolean removeArtwork(Artwork artwork) {
        ExhibitionArtwork found = null;
        if (getArtworks() == null)
            return false;
        for (ExhibitionArtwork exhiArt : getArtworks()) {
            if (exhiArt.getArtworkId().longValue() == artwork.getId().longValue()) {
                found = exhiArt;
                break;
            }
        }
        if (found != null) {
            return getArtworks().remove(found);
        }
        return false;
    }

    public boolean removePhoto(Image image) {
        List<ExhibitionPhoto> photos = getPhotos();
        if (photos == null)
            return false;
        ExhibitionPhoto found = null;
        for (ExhibitionPhoto photo : photos) {
            if (photo.getImageId().longValue() == image.getId().longValue()) {
                found = photo;
                break;
            }
        }
        if (found != null) {
            return getPhotos().remove(found);
        }
        return false;
    }

    public Long getArtistId() {
        return artistId;
    }

    public void setArtistId(Long artistId) {
        this.artistId = artistId;
    }
}
